package com.guide.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.guide.bizdto.AccountSel;
import com.guide.bizdto.IndexSel;
import com.guide.bizdto.UserInfoParam;
import com.guide.dao.AccountDao;
import com.guide.dao.GuideApplyDao;
import com.guide.dao.GuideDao;
import com.guide.dao.PersonalDao;
import com.guide.dao.TravelTeamDao;
import com.guide.dao.TravelorgDao;
import com.guide.domain.Account;
import com.guide.domain.Guide;
import com.guide.domain.GuideApply;
import com.guide.domain.Personal;
import com.guide.domain.TravelTeam;
import com.guide.domain.Travelorg;
import com.guide.enums.ErrorCodeEnum;
import com.guide.exception.ServiceException;
import com.guide.service.AccountService;
import com.guide.utils.CommonUtils;
import com.guide.utils.ConstantUtils;
@Service(value="accountService")
public class AccountServiceImpl implements AccountService {
	private static final Logger logger = LoggerFactory.getLogger(AccountServiceImpl.class);

	//private Date nowTime  = new Date();
	@Autowired
	private AccountDao accountDao;
	
	@Autowired
	private TravelorgDao travelorgDao;
	
	@Autowired
	private PersonalDao personalDao;
	
	@Autowired
	private GuideDao guideDao;
	
	@Autowired
	private TravelTeamDao travelTeamDao;;
	
	@Autowired
	private GuideApplyDao guideApplyDao;
	
	
	
	@Override
	public Account login(UserInfoParam userInfoParam) {
		// TODO Auto-generated method stub
		Account account = checkUserInfo(userInfoParam);
		//account肯定不是null，取真是的基本信息楼
		return account;
	}
	
	/**
	 * 登陆
	 * @param userInfoParam
	 * @return
	 */
	
	public Account checkUserInfo(UserInfoParam userInfoParam) {
		//通过用户名获取
		Account account = accountDao.getAccountByName(userInfoParam.getUserName());
		if(account == null) {//用户名不存在
			throw new ServiceException(ErrorCodeEnum.CODE_GUIDE_USERNMAE_NOTEXIST_ERROR);
		}else {
			//校验密码，如果密码正确，再校验审核状态
			logger.error("loginName--"+userInfoParam.getUserName()+"---loginPass"+userInfoParam.getPassword());
			String pass = CommonUtils.MD5Password(userInfoParam.getPassword(), account.getSalt());
			if(!pass.equals(account.getPassword())) {
				throw new ServiceException(ErrorCodeEnum.CODE_GUIDE_PASS_ERROR);
			}
			/*if(account.getStatus()== ConstantUtils.REGISTER_APPLY_0) {
				throw new ServiceException(ErrorCodeEnum.CODE_GUIDE_REGISTER_NO_APPLY_ERROR);
			}*/
		}
		//返回账号信息，因为要通过userId和userType来取得用户的真正的基本信息
		return account;
		
	}
	
	@Override
	@Transactional
	public Account register(UserInfoParam userInfoParam) {//因为注册后还需要审核，所以注册后直接跳到一个提示页面，告诉用户注册后的流程
		Account account = param2Account(userInfoParam);//用户名排重，再根据不同的身份进行排重，两个排除 
		if (userInfoParam.getUserType()==ConstantUtils.ACCOUNT_TYPE_0) {//旅行社
			Travelorg travelorg = param2Travelorg(userInfoParam,account.getUserId());
			travelorgDao.insertTravelorg(travelorg);
		}else if (userInfoParam.getUserType()==ConstantUtils.ACCOUNT_TYPE_1) {//个人
			Personal personal = param2Personal(userInfoParam,account.getUserId());
			personalDao.insertPersonal(personal);
		}else if (userInfoParam.getUserType()==ConstantUtils.ACCOUNT_TYPE_2) {//导游     
			Guide guide = param2Guide(userInfoParam,account.getUserId());
			guideDao.insertGuide(guide);
		}
		return account;
	}
	@Override
	@Transactional
	public void modifyAccountDetail(Account account, UserInfoParam userInfoParam) {
		if (account.getUserType()==ConstantUtils.ACCOUNT_TYPE_0) {//旅行社
			Travelorg travelorg = param2Travelorg(userInfoParam,account.getUserId());
			travelorg.setId(Long.valueOf(userInfoParam.getId()));
			travelorg.setMtime(new Date());
			travelorgDao.updateByPrimaryKeySelective(travelorg);
		}else if (account.getUserType()==ConstantUtils.ACCOUNT_TYPE_1) {//个人
			Personal personal = param2Personal(userInfoParam,account.getUserId());
			personal.setId(Long.valueOf(userInfoParam.getId()));
			personal.setMtime(new Date());
			personalDao.updateByPrimaryKeySelective(personal);
		}else if (account.getUserType()==ConstantUtils.ACCOUNT_TYPE_2) {//导游     
			Guide guide = param2Guide(userInfoParam,account.getUserId());
			guide.setId(Long.valueOf(userInfoParam.getId()));
			guide.setMtime(new Date());
			guideDao.updateByPrimaryKeySelective(guide);
		}
		if(!StringUtils.isEmpty(userInfoParam.getPassword())) {
			String salt = CommonUtils.getRandomString(6);
			account.setSalt(salt);
			logger.error("userName--"+account.getUserName()+"-----password----"+userInfoParam.getPassword());
			account.setPassword(CommonUtils.MD5Password(userInfoParam.getPassword(), salt));
			account.setShowPass(userInfoParam.getPassword());
			account.setMtime(new Date());
			accountDao.modifyAccount(account);
		}
		
	}
	
	private Account param2Account(UserInfoParam userInfoParam) {//记得根据不同类型的用户进行排重
		Account account = accountDao.getAccountByName(userInfoParam.getUserName());
		if(account!=null) {
			throw new ServiceException(ErrorCodeEnum.CODE_GUIDE_USERNMAE_EXIST_ERROR);
		}else{//判断各种用户排重方式
			if(userInfoParam.getUserType()==ConstantUtils.ACCOUNT_TYPE_0) {
				if(travelorgDao.getTravelorgBylicnumAndbuslicnum(userInfoParam.getLicnum(), userInfoParam.getBuslicnum())!=null){
					throw new ServiceException(ErrorCodeEnum.CODE_GUIDE_TRAVELORG_EXIST_ERROR);
				}
			}else if(userInfoParam.getUserType()==ConstantUtils.ACCOUNT_TYPE_1) {
				if(personalDao.getPersonalByIdnum(userInfoParam.getIdnum())!=null){
					throw new ServiceException(ErrorCodeEnum.CODE_GUIDE_PERSONAL_EXIST_ERROR);
				}
			}else if(userInfoParam.getUserType()==ConstantUtils.ACCOUNT_TYPE_2) {
				if(guideDao.getGuideByIdnum(userInfoParam.getIdnum())!=null){
					throw new ServiceException(ErrorCodeEnum.CODE_GUIDE_GUIDE_EXIST_ERROR);
				}
			}
		}
		account = new Account();
		account.setUserName(userInfoParam.getUserName());
		account.setUserType(userInfoParam.getUserType());
		String salt = CommonUtils.getRandomString(6);
		account.setSalt(salt);
		logger.error("userName--"+userInfoParam.getUserName()+"-----password----"+userInfoParam.getPassword());
		account.setPassword(CommonUtils.MD5Password(userInfoParam.getPassword(), salt));
		account.setShowPass(userInfoParam.getPassword());
		account.setStatus(ConstantUtils.REGISTER_APPLY_0);
		account.setCtime(new Date());
		account.setMtime(new Date());
		accountDao.insertAccount(account);
		return account;
	}
	
	private Travelorg param2Travelorg(UserInfoParam userInfoParam,Long userId) {
		Travelorg travelorg  = new Travelorg();
		travelorg.setUserId(userId);
		travelorg.setName(userInfoParam.getName());
		travelorg.setLicnum(userInfoParam.getLicnum());
		travelorg.setBuslicnum(userInfoParam.getBuslicnum());
		travelorg.setCreateTime(CommonUtils.StrToDate(userInfoParam.getCreateTime()));
		travelorg.setContact(userInfoParam.getContact());
		travelorg.setPhone(userInfoParam.getPhone());
		travelorg.setCity(userInfoParam.getCity());
		travelorg.setLevel(userInfoParam.getLevel());
		travelorg.setSite(userInfoParam.getSite());
		travelorg.setStatus(userInfoParam.getStatus());
		travelorg.setEmail(userInfoParam.getEmail());
		travelorg.setPhoto(userInfoParam.getPhoto());
		travelorg.setDescription(CommonUtils.unescape(userInfoParam.getDescription()));
		travelorg.setCtime(new Date());
		travelorg.setMtime(new Date());
		return travelorg;
	}
	
	private List<UserInfoParam> travelorg2ParamList(List<Travelorg> travelorgs){
		List<UserInfoParam> userInfoParams = new ArrayList<UserInfoParam>();
		if(!CollectionUtils.isEmpty(travelorgs)){
			for(Travelorg travelorg:travelorgs) {
				userInfoParams.add(travelorg2Param(travelorg,accountDao.getAccountById(travelorg.getUserId())));
			}
		}
		return userInfoParams;
	}
	
	private UserInfoParam  travelorg2Param(Travelorg travelorg,Account account) {
		UserInfoParam userInfoParam  = new UserInfoParam();
		userInfoParam.setId(String.valueOf(travelorg.getId()));
		userInfoParam.setUserId(String.valueOf(travelorg.getUserId()));
		if(account!=null){
			userInfoParam.setUserName(account.getUserName());
			userInfoParam.setUserType(account.getUserType());
			userInfoParam.setStatus(account.getStatus());
		}
		
		userInfoParam.setName(travelorg.getName());
		userInfoParam.setLicnum(travelorg.getLicnum());
		userInfoParam.setBuslicnum(travelorg.getBuslicnum());
		userInfoParam.setCreateTime(CommonUtils.DateToStr(travelorg.getCreateTime(), "yyyy-MM-dd"));
		userInfoParam.setContact(travelorg.getContact());
		userInfoParam.setPhone(travelorg.getPhone());
		userInfoParam.setCity(travelorg.getCity());
		userInfoParam.setLevel(travelorg.getLevel());
		userInfoParam.setSite(travelorg.getSite());
		
		userInfoParam.setEmail(travelorg.getEmail());
		userInfoParam.setPhoto(travelorg.getPhoto());
		userInfoParam.setDescription(travelorg.getDescription());
		userInfoParam.setCtime(CommonUtils.DateToStr(travelorg.getCtime(), "yyyy-MM-dd"));
		userInfoParam.setMtime(CommonUtils.DateToStr(travelorg.getMtime(), "yyyy-MM-dd"));
		return userInfoParam;
	}
	
	private Personal param2Personal(UserInfoParam userInfoParam,Long userId) {
		Personal personal  = new Personal();
		personal.setUserId(userId);
		personal.setIdnum(userInfoParam.getIdnum());
		personal.setName(userInfoParam.getName());
		personal.setEmail(userInfoParam.getEmail());
		personal.setPhone(userInfoParam.getPhone());
		personal.setStatus(userInfoParam.getStatus());
		personal.setPhoto(userInfoParam.getPhoto());
		personal.setDescription(CommonUtils.unescape(userInfoParam.getDescription()));
		personal.setCtime(new Date());
		personal.setMtime(new Date());
		return personal;
	}
	
	private UserInfoParam personal2Param(Personal personal,Account account) {
		UserInfoParam userInfoParam = new UserInfoParam();
		userInfoParam.setId(String.valueOf(personal.getId()));
		userInfoParam.setUserId(String.valueOf(personal.getUserId()));
		if(account!=null) {
			userInfoParam.setUserName(account.getUserName());
			userInfoParam.setUserType(account.getUserType());
			userInfoParam.setStatus(account.getStatus());
		}
		userInfoParam.setIdnum(personal.getIdnum());
		userInfoParam.setName(personal.getName());
		userInfoParam.setEmail(personal.getEmail());
		userInfoParam.setPhone(personal.getPhone());
		
		userInfoParam.setPhoto(personal.getPhoto());
		userInfoParam.setDescription(personal.getDescription());
		userInfoParam.setCtime(CommonUtils.DateToStr(personal.getCtime(), "yyyy-MM-dd"));
		userInfoParam.setMtime(CommonUtils.DateToStr(personal.getMtime(), "yyyy-MM-dd"));
		return userInfoParam;
	}
	
	private Guide param2Guide(UserInfoParam userInfoParam,Long userId) {
		Guide guide  = new Guide();
		guide.setUserId(userId);
		guide.setIdnum(userInfoParam.getIdnum());
		guide.setName(userInfoParam.getName());
		guide.setEmail(userInfoParam.getEmail());
		guide.setGender(userInfoParam.getGender());
		guide.setLanguage(userInfoParam.getLanguage());
		guide.setLevel(userInfoParam.getLevel());
		guide.setPhone(userInfoParam.getPhone());
		guide.setCity(userInfoParam.getCity());
		guide.setGoodatcity(userInfoParam.getGoodatcity());
		guide.setGuidecost(userInfoParam.getGuidecost());
		guide.setGuidenum(userInfoParam.getGuidenum());
		guide.setIsoutbound(userInfoParam.getIsoutbound());
		guide.setPhoto(userInfoParam.getPhoto());
		guide.setStatus(userInfoParam.getStatus());
		guide.setWorkyear(userInfoParam.getWorkyear());
		guide.setDescription(CommonUtils.unescape(userInfoParam.getDescription()));
		guide.setCtime(new Date());
		guide.setMtime(new Date());
		return guide;
	}
	
	private List<UserInfoParam> guide2ParamList(List<Guide> guides){
		List<UserInfoParam> userInfoParams = new ArrayList<UserInfoParam>();
		if(!CollectionUtils.isEmpty(guides)){
			for(Guide guide:guides) {
				userInfoParams.add(guide2Param(guide,accountDao.getAccountById(guide.getUserId())));
			}
		}
		return userInfoParams;
	}
	
	private UserInfoParam guide2Param(Guide guide,Account account) {
		UserInfoParam userInfoParam  = new UserInfoParam();
		userInfoParam.setId(String.valueOf(guide.getId()));
		userInfoParam.setUserId(String.valueOf(guide.getUserId()));
		if(account!=null) {
			userInfoParam.setUserName(account.getUserName());
			userInfoParam.setUserType(account.getUserType());
			userInfoParam.setStatus(account.getStatus());
		}
		userInfoParam.setIdnum(guide.getIdnum());
		userInfoParam.setName(guide.getName());
		userInfoParam.setEmail(guide.getEmail());
		userInfoParam.setGender(guide.getGender());
		userInfoParam.setLanguage(guide.getLanguage());
		userInfoParam.setLevel(guide.getLevel());
		userInfoParam.setPhone(guide.getPhone());
		userInfoParam.setCity(guide.getCity());
		userInfoParam.setGoodatcity(guide.getGoodatcity());
		userInfoParam.setGuidecost(guide.getGuidecost());
		userInfoParam.setGuidenum(guide.getGuidenum());
		userInfoParam.setIsoutbound(guide.getIsoutbound());
		userInfoParam.setPhoto(guide.getPhoto());
		userInfoParam.setWorkyear(guide.getWorkyear());
		userInfoParam.setDescription(guide.getDescription());
		userInfoParam.setCtime(CommonUtils.DateToStr(guide.getCtime(), "yyyy-MM-dd"));
		userInfoParam.setMtime(CommonUtils.DateToStr(guide.getMtime(), "yyyy-MM-dd"));
		return userInfoParam;
	}

	@Override
	public Travelorg getTravelorgByUserId(Long userId) {
		// TODO Auto-generated method stub
		return travelorgDao.getTravelorgByUserId(userId);
	}

	@Override
	public UserInfoParam getAccountDetailByAccount(Account account) {
		if(account.getUserType()==ConstantUtils.ACCOUNT_TYPE_0) {
			return travelorg2Param(travelorgDao.getTravelorgByUserId(account.getUserId()),account);
		}else if(account.getUserType()==ConstantUtils.ACCOUNT_TYPE_1) {
			return personal2Param(personalDao.getPersonalByUserId(account.getUserId()),account);
		}else if(account.getUserType()==ConstantUtils.ACCOUNT_TYPE_2){
			return guide2Param(guideDao.getGuideByUserId(account.getUserId()),account);
		}
		return null;
	}

	@Override
	public UserInfoParam getTravelorgById(Long id) {
		// TODO Auto-generated method stub
		Travelorg travelorg = travelorgDao.getTravelorgById(id);
		
		if(travelorg!=null) {
			Account account = accountDao.getAccountById(travelorg.getUserId());
			return travelorg2Param(travelorg,account);
		}
		return new UserInfoParam();
	}

	@Override
	public Account getAccountByUserName(String userName) {
		// TODO Auto-generated method stub
		return accountDao.getAccountByName(userName);
	}

	@Override
	public Account getAccountById(Long id) {
		// TODO Auto-generated method stub
		return accountDao.getAccountById(id);
	}

	@Override
	public Personal getPersonalByUserId(Long userId) {
		// TODO Auto-generated method stub
		return personalDao.getPersonalByUserId(userId);
	}



	@Override
	public void modifyAccount(Account account) {
		accountDao.modifyAccount(account);
		
	}

	@Override
	public Map<String, Object> getAccountList(AccountSel sel) {
			// TODO Auto-generated method stub
			List<Account> accounts = accountDao.getAccountList(sel);
			List<UserInfoParam>  params = new ArrayList<UserInfoParam>();
			if(!CollectionUtils.isEmpty(accounts)) {
				for(Account account:accounts) {
					/*UserInfoParam userInfoParam = new UserInfoParam();
					userInfoParam.setId(String.valueOf(account.getUserId()));
					userInfoParam.setUserId(String.valueOf(account.getUserId()));
					userInfoParam.setUserName(account.getUserName());
					userInfoParam.setUserType(account.getUserType());
					userInfoParam.setCtime(CommonUtils.DateToStr(account.getCtime(), "yyyy-MM-dd HH:mm:ss"));
					userInfoParam.setMtime(CommonUtils.DateToStr(account.getMtime(), "yyyy-MM-dd HH:mm:ss"));*/
					UserInfoParam tempParam  = this.getAccountDetailByAccount(account);
					tempParam.setShowPass(account.getShowPass());
					params.add(tempParam);
				}
			}
			Map<String, Object> retMap = new HashMap<String, Object>();
			retMap.put(ConstantUtils.DATE_LIST,params);
			retMap.put(ConstantUtils.TOTAL_COUNT, accountDao.countAccount(sel));
			return retMap;
	}

	@Override
	public void adminModifyPass(AccountSel accountSel,Account account) {
		// TODO Auto-generated method stub
		//accountDao.getAccountById(userId)
		String pass = CommonUtils.MD5Password(accountSel.getOldPass(), account.getSalt());
		if(!pass.equals(account.getPassword())) {
			throw new ServiceException(ErrorCodeEnum.CODE_GUIDE_PASS_ERROR,"---原密码错误");
		}
		String newPass = CommonUtils.MD5Password(accountSel.getNewPass(), account.getSalt());
		Account accountNew = new Account();
		accountNew.setUserId(account.getUserId());
		accountNew.setPassword(newPass);
		accountNew.setShowPass(accountSel.getNewPass());
		accountNew.setMtime(new Date());
		accountDao.modifyAccount(accountNew);
	}

	@Override
	public Map<String, Object> getGuideListByScore(IndexSel indexSel) {
		// TODO Auto-generated method stub
		List<UserInfoParam> guideList = guide2ParamList(guideDao.getGuideListByIndex(indexSel));
		Map<String, Object> retMap = new HashMap<String, Object>();
		retMap.put(ConstantUtils.DATE_LIST, guideList);
		retMap.put(ConstantUtils.TOTAL_COUNT, guideDao.countGuideListByIndex(indexSel));
		return retMap;
	}

	@Override
	public Map<String, Object> getTravelorgListByScore(IndexSel indexSel) {
		List<UserInfoParam> travelorgList = travelorg2ParamList(travelorgDao.getTravelorgListByIndex(indexSel));
		Map<String, Object> retMap = new HashMap<String, Object>();
		retMap.put(ConstantUtils.DATE_LIST, travelorgList);
		retMap.put(ConstantUtils.TOTAL_COUNT, travelorgDao.countTravelorgListByIndex(indexSel));
		return retMap;
	}

	@Override
	public UserInfoParam getAccountDetailByTeamId(Long teamId) {
		// TODO Auto-generated method stub
		TravelTeam travelTeam = travelTeamDao.getTravelTeamById(teamId);
		Account account = accountDao.getAccountById(travelTeam.getUserId());
		return this.getAccountDetailByAccount(account);
	}

	@Override
	public boolean checkAccountPrefect(Account account) {
		if(account.getUserType()==ConstantUtils.ACCOUNT_TYPE_0) {
			Travelorg travelorg = travelorgDao.getTravelorgByUserId(account.getUserId());
			//成立时间，级别，网址，邮箱，照片
			if(travelorg.getCreateTime()==null) {
				return false;
			}else if(travelorg.getLevel()==null) {
				return false;
			}else if(StringUtils.isEmpty(travelorg.getSite())) {
				return false;
			}else if(StringUtils.isEmpty(travelorg.getEmail())){
				return false;
			}else if(StringUtils.isEmpty(travelorg.getPhoto())){
				return false;
			}
		}else if(account.getUserType()==ConstantUtils.ACCOUNT_TYPE_1) {
			Personal personal  = personalDao.getPersonalByUserId(account.getUserId());
			//邮箱，照片
			if(personal.getEmail()==null) {
				return false;
			}else if(personal.getPhoto()==null) {
				return false;
			}
		}else if(account.getUserType()==ConstantUtils.ACCOUNT_TYPE_2){
			Guide guide = guideDao.getGuideByUserId(account.getUserId());
			//导游证号（有些大学生没有，所以选填）,性别，工作年限，级别，语种，是否出境带队，
			//擅长讲解城市，期望导服，备注，邮箱，照片
			if(StringUtils.isEmpty(guide.getGuidenum())) {
				return false;
			}else if(guide.getGender()==null) {
				return false;
			}else if(guide.getWorkyear()==null) {
				return false;
			}else if(guide.getLevel()==null){
				return false;
			}else if(StringUtils.isEmpty(guide.getLanguage())){
				return false;
			}else if(guide.getIsoutbound()==null) {
				return false;
			}else if(StringUtils.isEmpty(guide.getGoodatcity())) {
				return false;
			}else if(guide.getGuidecost()==null) {
				return false;
			}else if(StringUtils.isEmpty(guide.getDescription())){
				return false;
			}else if(StringUtils.isEmpty(guide.getEmail())){
				return false;
			}else if(StringUtils.isEmpty(guide.getPhoto())){
				return false;
			}
		}
		return true;
	}

	@Override
	public UserInfoParam getGuideById(Long id) {
		Guide guide = guideDao.getGuideById(id);
		if(guide!=null) {
			Account account  = accountDao.getAccountById(guide.getUserId());
			return guide2Param(guide,account);
		}
		return new UserInfoParam();
	}

	@Override
	public UserInfoParam getApplyGuideByConfirm(Long teamId) {
		// TODO Auto-generated method stub
		GuideApply guideApply = guideApplyDao.getApplyGuideByConfirm(teamId);
		if(guideApply!=null) {
			//Account account = accountDao.getAccountById(userId)
			Guide guide = guideDao.getGuideById(guideApply.getGuideId());
			Account account  = accountDao.getAccountById(guide.getUserId());
			return guide2Param(guide,account);
		}else{
			throw new ServiceException(ErrorCodeEnum.SYSTEM_ERROR);
		}
	}

	@Override
	public UserInfoParam getPersonalById(Long id) {
		// TODO Auto-generated method stub
		Personal personal =personalDao.getPersonalById(id);
		if(personal!=null) {
			Account account = accountDao.getAccountById(personal.getUserId());
			return personal2Param(personal,account);
		}
		return null;
	}

	
	
	

}
